# -*- coding: utf-8 -*-
'''
Created on 2013-4-11

@author: cl.lam
'''
import flask, traceback
from flask import current_app as app
from flask import g, render_template, flash, session, redirect, url_for, request, request_finished, jsonify
from flask.blueprints import Blueprint

from sys2do.views import BasicView
from sys2do.util.decorator import templated, allPermission
from sys2do.model import db, qry
from sys2do.model.logic import InventoryProduct, InventoryLocation, SO, SODtl, InventoryNote, InventoryNoteDtl, FinNote, FinNoteDtl, InventoryNoteDtlItem
from sys2do.model.master import Payterm, Product, Item, Member
from sys2do.model.system import SysLog
from sys2do.util.logic_helper import getCurrentShopID, getCurrentShop, checkLogin, getCurrentShopProfile

from sys2do.util.common import _g
from sys2do.constant import *

from sqlalchemy import and_, or_

from ext.view import extract_inline_list

__all__ = ['bpSale']

bpSale = Blueprint( 'bpSale', __name__, )

@bpSale.before_request
def addActivetab():
    session[TAB_FLAG] = TAB_HOME

@bpSale.before_request
def _b():
    return checkLogin()

class SaleView( BasicView ):

    template_folder = 'sale'

    @templated( 'index.html' )
    def index( self ):
        form = None
        if request.method == 'POST':
            form = SrhForm( request.form )
            session[url_for( '.view' )] = form
        else:
            form = session.get( url_for( '.view' ), SrhForm( request.form ) )
        form.url = url_for( '.view' )
        cds = [SO.shopID == getCurrentShopID(), SO.active == ACTIVE]
        if form.no.data: cds.append( SO.no.like( '%%%s%%' % form.no.data ) )
        if form.soldTimeFrom.data : cds.append( SO.soldTime > form.soldTimeFrom.data )
        if form.soldTimeTo.data : cds.append( SO.soldTime < form.soldTimeTo.data )

        '''
        spobj = getCurrentShopProfile()
        pdts = qry( Product, InventoryLocation, InventoryProduct ).filter( and_( Product.active == 0, InventoryProduct.active == 0, InventoryLocation.active == 0,
                                 Product.id == InventoryProduct.pdtID, InventoryLocation.id == InventoryProduct.ivtID,
                                 InventoryProduct.qty > 0 ,
                                 or_( InventoryLocation.fullPath.like( '%s|' % spobj.inventoryID ), InventoryLocation.id == spobj.inventoryID )
                                 ) )
        print '#'*40
        print pdts
        print pdts.all()
        '''
        return {'result': SO.findBy( cds ), 'form': form}

    @templated( 'add.html' )
    def add( self ):
        return {'shop': getCurrentShop(), 'payTerms': Payterm.all(), 'so': SO.init(), 'fromAction': 'add'}

    @templated( 'add.html' )
    def edit( self ):
        return {'shop': getCurrentShop(), 'payTerms': Payterm.all(), 'so': SO.getBy( [SO.id == _g( 'id' )] ), 'fromAction': 'edit'}

    @templated( 'view.html' )
    def view( self ):
        return {'shop': getCurrentShop(), 'so': SO.getBy( [SO.id == _g( 'id' )] )}

    @templated( 'stamp.html' )
    def stamp( self ):
        return {'shop': getCurrentShop(), 'so': SO.getBy( [SO.id == _g( 'id' )] )}

    @templated( 'view_log.html' )
    def viewLog( self ):
        return {'so': SO.getBy( [SO.id == _g( 'id' )] )}

    def save( self ):
        if request.method == 'POST':
            kw = request.form.to_dict()
            member_no = kw['query_member']
            member = Member.getBy( [Member.no == member_no] ) if member_no else None
            kw = extract_inline_list( 'so', **kw )
            kw = extract_inline_list( 'product_set', **kw )
            so_hdr = None
            try:
                if kw['fromAction'] == 'add':
                    kw['so']['shopID'] = getCurrentShop().id
                    so_hdr = SO.saveNew( memberID = member.id if member else None, **kw['so'] )
                    so_dtls = kw['product_set']
                    for i in so_dtls:
                        so_dtl = SODtl.saveNew( hdrID = so_hdr.id, **i )
                        so_dtl.copyPdtInfo( so_dtl.pdt )
                    db.add( SysLog( refClz = so_hdr.__class__.__name__, type = LOG_TYPE_CREATE, refID = so_hdr.id, ) )
                    flash( MSG_SAVE_SUCC, MESSAGE_INFO )
                elif kw['fromAction'] == 'edit':
                    so_hdr = SO.get( kw['so']['id'] )
                    so_hdr.saveEdit( memberID = member.id if member else None, **kw['so'] )
                    so_dtls = kw['product_set']
                    old_dtl_map = {}
                    for i in so_hdr.dtls:
                        old_dtl_map[i.id] = i
                    for i in so_dtls:
                        so_dtl = None
                        if i.get( 'id', None ):
                            so_dtl = SODtl.get( i['id'] )
                            so_dtl.saveEdit( **i )
                            del old_dtl_map[int( so_dtl.id )]
                        else:
                            so_dtl = SODtl.saveNew( hdrID = so_hdr.id, **i )

                        so_dtl.copyPdtInfo( so_dtl.pdt )
                    for k, v in old_dtl_map.iteritems():
                        v.active = INACTIVE
                    db.add( SysLog( refClz = so_hdr.__class__.__name__, type = LOG_TYPE_UPDATE, refID = so_hdr.id, ) )
                    flash( MSG_UPDATE_SUCC, MESSAGE_INFO )
                db.commit()
                return redirect( url_for( '.view', action = 'view', id = so_hdr.id ) )
            except Exception, e:
                flash( MSG_SERVER_ERROR, MESSAGE_ERROR )
                app.logger.exception( str( e ) )
                db.rollback()
                return redirect( url_for( '.view', action = 'index' ) )
        else:
            return redirect( url_for( '.view', action = 'index' ) )

    def searchPdt( self ):
        cds = []
        if _g( 'no' ) : cds.append( Item.no.like( '%%%s%%' % _g( 'no' ) ) )
        if _g( 'name' ) : cds.append( Product.name.like( '%%%s%%' % _g( 'name' ) ) )
        products = [{'no': i.no, 'name': i.pdt.name} for i in InventoryProduct.findItemsBy( shopID = getCurrentShopID(), cds = cds )]
        return jsonify( 
            products = products
        )

    def getPdt( self ):
        item_no = _g( 'no' )
        item = Item.getBy( [Item.no == item_no] )
        itemDict = None
        pdtDict = None
        inventoryLocations = []
        if item:
            itemDict = item.toJson('id', 'no', 'ivtID')
            product = item.pdt
            pdtDict = product.toJson( 'id', 'no', 'name', 'pPrice', 'sPrice', 'fee', 'thumbUrl' )
            for i in product.shopIvtPdts:
                if i.ivt.name not in IVTLT_VIRTUAL_LIST:
                    if i.availableQty:
                        ivtDict = {'id': i.ivt.id, 'name': i.ivt.fullPath, 'availableQty': i.availableQty}
                        inventoryLocations.append( ivtDict )
        return jsonify( item = itemDict, product = pdtDict, shopIvtPdts = inventoryLocations )

    def approve( self ):
        try:
            so = SO.getBy( [SO.id == _g( 'id' )] )
            if so.status == SO_NEW:
                so.status = SO_APPROVE
                shop = getCurrentShop()
                soldoutIvt = InventoryLocation.getSoldOutIvt()
                ivtnt = InventoryNote.saveNew( shopID = shop.id, ivtID = soldoutIvt.id,
                                               direction = IVTNT_OUT, type = 'SALE', refer = so.no,
                                               )
                finnt = FinNote.saveNew( shopID = shop.id, direction = FIN_IN, refer = so.no, amount = so.realAmount )

                ivt = shop.shopProfile[0].inventory

                for dtl in so.dtls:
                    product = Product.get( dtl.pdtID )
                    for ivtQty in dtl.ivtQtyObjs:
                        if ivtQty['qty']:
                            ivtntDtl = InventoryNoteDtl.saveNew( hdrID = ivtnt.id, pdtID = dtl.pdtID, 
                                qty = ivtQty['qty'], sIvtLtnID=ivtQty['ivtID'], 
                                dIvtLtnID = soldoutIvt.id)
                            ivtntDtl.copyPdtInfo( dtl.pdt )
                            '''
                            for ivtItemNO in ivtQty['itemNOs']:
                                InventoryNoteDtlItem.saveNew( hdrID = ivtnt.id, dtlID = ivtntDtl.id, itemID = Item.getBy( [Item.no==ivtItemNO] ).id )
                            '''
                            ivtntDtl.itemList = ivtQty['itemNOs']
                            InventoryProduct.goingToMove( ivtQty['ivtID'], soldoutIvt.id, dtl.pdtID, dtl.qty )
                            #InventoryProduct.addOrUpdate( ivtQty['ivtID'], product.id, -(ivtQty['qty']) )
                    finntDtl = FinNoteDtl.saveNew( hdrID = finnt.id, itemName = dtl.pdtname,
                        desc = product.makeDesc(), refer = dtl.id, price = dtl.realPrice,
                        qty = dtl.qty, amount = dtl.realAmount )
                db.add( SysLog.create( dict( refClz = so.__class__.__name__, type = LOG_TYPE_APPROVE, refID = so.id ) ) )
                db.add( SysLog.create( dict( refClz = ivtnt.__class__.__name__, type = LOG_TYPE_CREATE, refID = ivtnt.id ) ) )
                db.add( SysLog.create( dict( refClz = finnt.__class__.__name__, type = LOG_TYPE_CREATE, refID = finnt.id ) ) )
            db.commit()
            flash( MSG_UPDATE_SUCC, MESSAGE_INFO )
            return redirect( url_for( '.view', action = 'view', id = so.id ) )
        except Exception, e:
            flash( MSG_SERVER_ERROR, MESSAGE_ERROR )
            app.logger.exception( str( e ) )
            db.rollback()
            return redirect( url_for( '.view', action = 'index' ) )

    def disapprove( self ):
        so = SO.getBy( [SO.id == _g( 'id' )] )
        if so.status == SO_NEW:
            so.status = SO_DISAPPROVE
        flash( MSG_UPDATE_SUCC, MESSAGE_INFO )
        return redirect( url_for( '.view', action = 'view', id = so.id ) )

    def delete( self ):
        try:
            obj = SO.get( _g( 'id' ) )
            if obj.status == SO_APPROVE:
                flash( MSG_NO_SUCH_ACTION, MESSAGE_ERROR )
            else:
                obj.active = INACTIVE
                db.add( SysLog.create( dict( refClz = obj.__class__.__name__, type = LOG_TYPE_DEL, refID = obj.id, ) ) )
                db.commit()
                flash( MSG_UPDATE_SUCC, MESSAGE_INFO )
        except:
            traceback.print_exc()
            db.rollback()
            flash( MSG_SERVER_ERROR, MESSAGE_ERROR )
        return redirect( url_for( '.view' ) )


bpSale.add_url_rule( '/', view_func = SaleView.as_view( 'view' ), defaults = {'action':'index'} )
bpSale.add_url_rule( '/<action>', view_func = SaleView.as_view( 'view' ) )

from wtforms import Form, TextField, SelectField
from sys2do.util.wt_helper import MyDateField

class SrhForm( Form ):
    no = TextField( u'系统编号', )
    soldTimeFrom = MyDateField( u'出售时间(开始)', )
    soldTimeTo = MyDateField( u'出售时间(结束)' )
